home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / gfx / x11 / twm_930531.lha / twm / parse.c < prev    next >
C/C++ Source or Header  |  1993-05-30  |  31KB  |  1,079 lines

  1. /*****************************************************************************/
  2. /**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
  3. /**                          Salt Lake City, Utah                           **/
  4. /**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
  5. /**                        Cambridge, Massachusetts                         **/
  6. /**                                                                         **/
  7. /**                           All Rights Reserved                           **/
  8. /**                                                                         **/
  9. /**    Permission to use, copy, modify, and distribute this software and    **/
  10. /**    its documentation  for  any  purpose  and  without  fee is hereby    **/
  11. /**    granted, provided that the above copyright notice appear  in  all    **/
  12. /**    copies and that both  that  copyright  notice  and  this  permis-    **/
  13. /**    sion  notice appear in supporting  documentation,  and  that  the    **/
  14. /**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
  15. /**    in publicity pertaining to distribution of the  software  without    **/
  16. /**    specific, written prior permission.                                  **/
  17. /**                                                                         **/
  18. /**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
  19. /**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
  20. /**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
  21. /**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
  22. /**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
  23. /**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
  24. /**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
  25. /**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
  26. /*****************************************************************************/
  27.  
  28.  
  29. /***********************************************************************
  30.  *
  31.  * $XConsortium: parse.c,v 1.52 91/07/12 09:59:37 dave Exp $
  32.  *
  33.  * parse the .twmrc file
  34.  *
  35.  * 17-Nov-87 Thomas E. LaStrange       File created
  36.  * 10-Oct-90 David M. Sternlicht       Storing saved colors on root
  37.  ***********************************************************************/
  38.  
  39. #include <stdio.h>
  40. #include <X11/Xos.h>
  41. #include <X11/Xmu/CharSet.h>
  42. #include "twm.h"
  43. #include "screen.h"
  44. #include "menus.h"
  45. #include "util.h"
  46. #include "gram.h"
  47. #include "parse.h"
  48. #include <X11/Xatom.h> 
  49.  
  50. #ifndef SYSTEM_INIT_FILE
  51. #define SYSTEM_INIT_FILE "/usr/lib/X11/twm/system.twmrc"
  52. #endif
  53. #define BUF_LEN 300
  54.  
  55. static FILE *twmrc;
  56. static int ptr = 0;
  57. static int len = 0;
  58. static char buff[BUF_LEN+1];
  59. static char overflowbuff[20];        /* really only need one */
  60. static int overflowlen;
  61. static char **stringListSource, *currentString;
  62. static int ParseUsePPosition();
  63.  
  64. extern int yylineno;
  65. extern FILE *yyin, *yyout;
  66. extern int mods;
  67.  
  68. int ConstrainedMoveTime = 400;        /* milliseconds, event times */
  69.  
  70. static int twmFileInput(), twmStringListInput();
  71. void twmUnput();
  72. int (*twmInputFunc)();
  73.  
  74. extern char *defTwmrc[];        /* default bindings */
  75.  
  76.  
  77. /***********************************************************************
  78.  *
  79.  *  Procedure:
  80.  *    ParseTwmrc - parse the .twmrc file
  81.  *
  82.  *  Inputs:
  83.  *    filename  - the filename to parse.  A NULL indicates $HOME/.twmrc
  84.  *
  85.  ***********************************************************************
  86.  */
  87.  
  88. static int doparse (ifunc, srctypename, srcname)
  89.     int (*ifunc)();
  90.     char *srctypename;
  91.     char *srcname;
  92. {
  93.     mods = 0;
  94.     ptr = 0;
  95.     len = 0;
  96.     yylineno = 1;
  97.     ParseError = FALSE;
  98.     twmInputFunc = ifunc;
  99.     overflowlen = 0;
  100.  
  101.     yyparse();
  102.  
  103.     if (ParseError) {
  104.     fprintf (stderr, "%s:  errors found in twm %s",
  105.          ProgramName, srctypename);
  106.     if (srcname) fprintf (stderr, " \"%s\"", srcname);
  107.     fprintf (stderr, "\n");
  108.     }
  109.     return (ParseError ? 0 : 1);
  110. }
  111.  
  112.  
  113. int ParseTwmrc (filename)
  114.     char *filename;
  115. {
  116.     int i;
  117.     char *home = NULL;
  118.     int homelen = 0;
  119.     char *cp = NULL;
  120.     char tmpfilename[257];
  121.  
  122.     /*
  123.      * If filename given, try it, else try ~/.twmrc.# then ~/.twmrc.  Then
  124.      * try system.twmrc; finally using built-in defaults.
  125.      */
  126.     for (twmrc = NULL, i = 0; !twmrc && i < 4; i++) {
  127.     switch (i) {
  128.       case 0:            /* -f filename */
  129.         cp = filename;
  130.         break;
  131.  
  132.       case 1:            /* ~/.twmrc.screennum */
  133.         if (!filename) {
  134.         home = getenv ("HOME");
  135.         if (home) {
  136.             homelen = strlen (home);
  137.             cp = tmpfilename;
  138.             (void) sprintf (tmpfilename, "%s/.twmrc.%d",
  139.                     home, Scr->screen);
  140.             break;
  141.         }
  142.         }
  143.         continue;
  144.  
  145.       case 2:            /* ~/.twmrc */
  146.         if (home) {
  147.         tmpfilename[homelen + 7] = '\0';
  148.         }
  149.         break;
  150.  
  151.       case 3:            /* system.twmrc */
  152.         cp = SYSTEM_INIT_FILE;
  153.         break;
  154.     }
  155.  
  156.     if (cp) twmrc = fopen (cp, "r");
  157.     }
  158.  
  159.     if (twmrc) {
  160.     int status;
  161.  
  162.     if (filename && cp != filename) {
  163.         fprintf (stderr,
  164.              "%s:  unable to open twmrc file %s, using %s instead\n",
  165.              ProgramName, filename, cp);
  166.     }
  167.     
  168.     /* had to put this line in to get my flex output
  169.      * to work with file input. (Michael Balzer)
  170.      */
  171.     yyin = twmrc;
  172.     
  173.     status = doparse (twmFileInput, "file", cp);
  174.     fclose (twmrc);
  175.     return status;
  176.     } else {
  177.     if (filename) {
  178.         fprintf (stderr,
  179.     "%s:  unable to open twmrc file %s, using built-in defaults instead\n",
  180.              ProgramName, filename);
  181.     }
  182.     return ParseStringList (defTwmrc);
  183.     }
  184. }
  185.  
  186. int ParseStringList (sl)
  187.     char **sl;
  188. {
  189.     stringListSource = sl;
  190.     currentString = *sl;
  191.     return doparse (twmStringListInput, "string list", (char *)NULL);
  192. }
  193.  
  194.  
  195. /***********************************************************************
  196.  *
  197.  *  Procedure:
  198.  *    twmFileInput - redefinition of the lex input routine for file input
  199.  *
  200.  *  Returned Value:
  201.  *    the next input character
  202.  *
  203.  ***********************************************************************
  204.  */
  205.  
  206. static int twmFileInput()
  207. {
  208.     if (overflowlen) return (int) overflowbuff[--overflowlen];
  209.  
  210.     while (ptr == len)
  211.     {
  212.     if (fgets(buff, BUF_LEN, twmrc) == NULL)
  213.         return 0;
  214.  
  215.     yylineno++;
  216.  
  217.     ptr = 0;
  218.     len = strlen(buff);
  219.     }
  220.     return ((int)buff[ptr++]);
  221. }
  222.  
  223. static int twmStringListInput()
  224. {
  225.     if (overflowlen) return (int) overflowbuff[--overflowlen];
  226.  
  227.     /*
  228.      * return the character currently pointed to
  229.      */
  230.     if (currentString) {
  231.     unsigned int c = (unsigned int) *currentString++;
  232.  
  233.     if (c) return c;        /* if non-nul char */
  234.     currentString = *++stringListSource;  /* advance to next bol */
  235.     return '\n';            /* but say that we hit last eol */
  236.     }
  237.     return 0;                /* eof */
  238. }
  239.  
  240.  
  241. /***********************************************************************
  242.  *
  243.  *  Procedure:
  244.  *    twmUnput - redefinition of the lex unput routine
  245.  *
  246.  *  Inputs:
  247.  *    c    - the character to push back onto the input stream
  248.  *
  249.  ***********************************************************************
  250.  */
  251.  
  252. void twmUnput (c)
  253.     int c;
  254. {
  255.     if (overflowlen < sizeof overflowbuff) {
  256.     overflowbuff[overflowlen++] = (char) c;
  257.     } else {
  258.     twmrc_error_prefix ();
  259.     fprintf (stderr, "unable to unput character (%d)\n",
  260.          c);
  261.     }
  262. }
  263.  
  264.  
  265. /***********************************************************************
  266.  *
  267.  *  Procedure:
  268.  *    TwmOutput - redefinition of the lex output routine
  269.  *
  270.  *  Inputs:
  271.  *    c    - the character to print
  272.  *
  273.  ***********************************************************************
  274.  */
  275.  
  276. void
  277. TwmOutput(c)
  278. {
  279.     putchar(c);
  280. }
  281.  
  282.  
  283. /**********************************************************************
  284.  *
  285.  *  Parsing table and routines
  286.  * 
  287.  ***********************************************************************/
  288.  
  289. typedef struct _TwmKeyword {
  290.     char *name;
  291.     int value;
  292.     int subnum;
  293. } TwmKeyword;
  294.  
  295. #define kw0_NoDefaults            1
  296. #define kw0_AutoRelativeResize        2
  297. #define kw0_ForceIcons            3
  298. #define kw0_NoIconManagers        4
  299. #define kw0_OpaqueMove            5
  300. #define kw0_InterpolateMenuColors    6
  301. #define kw0_NoVersion            7
  302. #define kw0_SortIconManager        8
  303. #define kw0_NoGrabServer        9
  304. #define kw0_NoMenuShadows        10
  305. #define kw0_NoRaiseOnMove        11
  306. #define kw0_NoRaiseOnResize        12
  307. #define kw0_NoRaiseOnDeiconify        13
  308. #define kw0_DontMoveOff            14
  309. #define kw0_NoBackingStore        15
  310. #define kw0_NoSaveUnders        16
  311. #define kw0_RestartPreviousState    17
  312. #define kw0_ClientBorderWidth        18
  313. #define kw0_NoTitleFocus        19
  314. #define kw0_RandomPlacement        20
  315. #define kw0_DecorateTransients        21
  316. #define kw0_ShowIconManager        22
  317. #define kw0_NoCaseSensitive        23
  318. #define kw0_NoRaiseOnWarp        24
  319. #define kw0_WarpUnmapped        25
  320.  
  321. #define kws_UsePPosition        1
  322. #define kws_IconFont            2
  323. #define kws_ResizeFont            3
  324. #define kws_MenuFont            4
  325. #define kws_TitleFont            5
  326. #define kws_IconManagerFont        6
  327. #define kws_UnknownIcon            7
  328. #define kws_IconDirectory        8
  329. #define kws_MaxWindowSize        9
  330.  
  331. #define kwn_ConstrainedMoveTime        1
  332. #define kwn_MoveDelta            2
  333. #define kwn_XorValue            3
  334. #define kwn_FramePadding        4
  335. #define kwn_TitlePadding        5
  336. #define kwn_ButtonIndent        6
  337. #define kwn_BorderWidth            7
  338. #define kwn_IconBorderWidth        8
  339. #define kwn_TitleButtonBorderWidth    9
  340.  
  341. #define kwcl_BorderColor        1
  342. #define kwcl_IconManagerHighlight    2
  343. #define kwcl_BorderTileForeground    3
  344. #define kwcl_BorderTileBackground    4
  345. #define kwcl_TitleForeground        5
  346. #define kwcl_TitleBackground        6
  347. #define kwcl_IconForeground        7
  348. #define kwcl_IconBackground        8
  349. #define kwcl_IconBorderColor        9
  350. #define kwcl_IconManagerForeground    10
  351. #define kwcl_IconManagerBackground    11
  352.  
  353. #define kwc_DefaultForeground        1
  354. #define kwc_DefaultBackground        2
  355. #define kwc_MenuForeground        3
  356. #define kwc_MenuBackground        4
  357. #define kwc_MenuTitleForeground        5
  358. #define kwc_MenuTitleBackground        6
  359. #define kwc_MenuShadowColor        7
  360.  
  361.  
  362. /*
  363.  * The following is sorted alphabetically according to name (which must be
  364.  * in lowercase and only contain the letters a-z).  It is fed to a binary
  365.  * search to parse keywords.
  366.  */
  367. static TwmKeyword keytable[] = { 
  368.     { "all",            ALL, 0 },
  369.     { "autoraise",        AUTO_RAISE, 0 },
  370.     { "autorelativeresize",    KEYWORD, kw0_AutoRelativeResize },
  371.     { "bordercolor",        CLKEYWORD, kwcl_BorderColor },
  372.     { "bordertilebackground",    CLKEYWORD, kwcl_BorderTileBackground },
  373.     { "bordertileforeground",    CLKEYWORD, kwcl_BorderTileForeground },
  374.     { "borderwidth",        NKEYWORD, kwn_BorderWidth },
  375.     { "button",            BUTTON, 0 },
  376.     { "buttonindent",        NKEYWORD, kwn_ButtonIndent },
  377.     { "c",            CONTROL, 0 },
  378.     { "center",            JKEYWORD, J_CENTER },
  379.     { "clientborderwidth",    KEYWORD, kw0_ClientBorderWidth },
  380.     { "color",            COLOR, 0 },
  381.     { "constrainedmovetime",    NKEYWORD, kwn_ConstrainedMoveTime },
  382.     { "control",        CONTROL, 0 },
  383.     { "cursors",        CURSORS, 0 },
  384.     { "decoratetransients",    KEYWORD, kw0_DecorateTransients },
  385.     { "defaultbackground",    CKEYWORD, kwc_DefaultBackground },
  386.     { "defaultforeground",    CKEYWORD, kwc_DefaultForeground },
  387.     { "defaultfunction",    DEFAULT_FUNCTION, 0 },
  388.     { "destroy",        KILL, 0 },
  389.     { "donticonifybyunmapping",    DONT_ICONIFY_BY_UNMAPPING, 0 },
  390.     { "dontmoveoff",        KEYWORD, kw0_DontMoveOff },
  391.     { "dontsqueezetitle",    DONT_SQUEEZE_TITLE, 0 },
  392.     { "east",            DKEYWORD, D_EAST },
  393.     { "f",            FRAME, 0 },
  394.     { "f.autoraise",        FKEYWORD, F_AUTORAISE },
  395.     { "f.backiconmgr",        FKEYWORD, F_BACKICONMGR },
  396.     { "f.beep",            FKEYWORD, F_BEEP },
  397.     { "f.bottomzoom",        FKEYWORD, F_BOTTOMZOOM },
  398.     { "f.circledown",        FKEYWORD, F_CIRCLEDOWN },
  399.     { "f.circleup",        FKEYWORD, F_CIRCLEUP },
  400.     { "f.colormap",        FSKEYWORD, F_COLORMAP },
  401.     { "f.cut",            FSKEYWORD, F_CUT },
  402.     { "f.cutfile",        FKEYWORD, F_CUTFILE },
  403.     { "f.deiconify",        FKEYWORD, F_DEICONIFY },
  404.     { "f.delete",        FKEYWORD, F_DELETE },
  405.     { "f.deltastop",        FKEYWORD, F_DELTASTOP },
  406.     { "f.destroy",        FKEYWORD, F_DESTROY },
  407.     { "f.downiconmgr",        FKEYWORD, F_DOWNICONMGR },
  408.     { "f.exec",            FSKEYWORD, F_EXEC },
  409.     { "f.file",            FSKEYWORD, F_FILE },
  410.     { "f.focus",        FKEYWORD, F_FOCUS },
  411.     { "f.forcemove",        FKEYWORD, F_FORCEMOVE },
  412.     { "f.forwiconmgr",        FKEYWORD, F_FORWICONMGR },
  413.     { "f.fullzoom",        FKEYWORD, F_FULLZOOM },
  414.     { "f.function",        FSKEYWORD, F_FUNCTION },
  415.     { "f.hbzoom",        FKEYWORD, F_BOTTOMZOOM },
  416.     { "f.hideiconmgr",        FKEYWORD, F_HIDELIST },
  417.     { "f.horizoom",        FKEYWORD, F_HORIZOOM },
  418.     { "f.htzoom",        FKEYWORD, F_TOPZOOM },
  419.     { "f.hzoom",        FKEYWORD, F_HORIZOOM },
  420.     { "f.iconify",        FKEYWORD, F_ICONIFY },
  421.     { "f.identify",        FKEYWORD, F_IDENTIFY },
  422.     { "f.lefticonmgr",        FKEYWORD, F_LEFTICONMGR },
  423.     { "f.leftzoom",        FKEYWORD, F_LEFTZOOM },
  424.     { "f.lower",        FKEYWORD, F_LOWER },
  425.     { "f.menu",            FSKEYWORD, F_MENU },
  426.     { "f.move",            FKEYWORD, F_MOVE },
  427.     { "f.nexticonmgr",        FKEYWORD, F_NEXTICONMGR },
  428.     { "f.nop",            FKEYWORD, F_NOP },
  429.     { "f.previconmgr",        FKEYWORD, F_PREVICONMGR },
  430.     { "f.quit",            FKEYWORD, F_QUIT },
  431.     { "f.raise",        FKEYWORD, F_RAISE },
  432.     { "f.raiselower",        FKEYWORD, F_RAISELOWER },
  433.     { "f.refresh",        FKEYWORD, F_REFRESH },
  434.     { "f.resize",        FKEYWORD, F_RESIZE },
  435.     { "f.restart",        FKEYWORD, F_RESTART },
  436.     { "f.righticonmgr",        FKEYWORD, F_RIGHTICONMGR },
  437.     { "f.rightzoom",        FKEYWORD, F_RIGHTZOOM },
  438.     { "f.saveyourself",        FKEYWORD, F_SAVEYOURSELF },
  439.     { "f.showiconmgr",        FKEYWORD, F_SHOWLIST },
  440.     { "f.sorticonmgr",        FKEYWORD, F_SORTICONMGR },
  441.     { "f.source",        FSKEYWORD, F_BEEP },  /* XXX - don't work */
  442.     { "f.title",        FKEYWORD, F_TITLE },
  443.     { "f.topzoom",        FKEYWORD, F_TOPZOOM },
  444.     { "f.twmrc",        FKEYWORD, F_RESTART },
  445.     { "f.unfocus",        FKEYWORD, F_UNFOCUS },
  446.     { "f.upiconmgr",        FKEYWORD, F_UPICONMGR },
  447.     { "f.version",        FKEYWORD, F_VERSION },
  448.     { "f.vlzoom",        FKEYWORD, F_LEFTZOOM },
  449.     { "f.vrzoom",        FKEYWORD, F_RIGHTZOOM },
  450.     { "f.warpring",        FSKEYWORD, F_WARPRING },
  451.     { "f.warpto",        FSKEYWORD, F_WARPTO },
  452.     { "f.warptoiconmgr",    FSKEYWORD, F_WARPTOICONMGR },
  453.     { "f.warptoscreen",        FSKEYWORD, F_WARPTOSCREEN },
  454.     { "f.winrefresh",        FKEYWORD, F_WINREFRESH },
  455.     { "f.zoom",            FKEYWORD, F_ZOOM },
  456.     { "forceicons",        KEYWORD, kw0_ForceIcons },
  457.     { "frame",            FRAME, 0 },
  458.     { "framepadding",        NKEYWORD, kwn_FramePadding },
  459.     { "function",        FUNCTION, 0 },
  460.     { "i",            ICON, 0 },
  461.     { "icon",            ICON, 0 },
  462.     { "iconbackground",        CLKEYWORD, kwcl_IconBackground },
  463.     { "iconbordercolor",    CLKEYWORD, kwcl_IconBorderColor },
  464.     { "iconborderwidth",    NKEYWORD, kwn_IconBorderWidth },
  465.     { "icondirectory",        SKEYWORD, kws_IconDirectory },
  466.     { "iconfont",        SKEYWORD, kws_IconFont },
  467.     { "iconforeground",        CLKEYWORD, kwcl_IconForeground },
  468.     { "iconifybyunmapping",    ICONIFY_BY_UNMAPPING, 0 },
  469.     { "iconmanagerbackground",    CLKEYWORD, kwcl_IconManagerBackground },
  470.     { "iconmanagerdontshow",    ICONMGR_NOSHOW, 0 },
  471.     { "iconmanagerfont",    SKEYWORD, kws_IconManagerFont },
  472.     { "iconmanagerforeground",    CLKEYWORD, kwcl_IconManagerForeground },
  473.     { "iconmanagergeometry",    ICONMGR_GEOMETRY, 0 },
  474.     { "iconmanagerhighlight",    CLKEYWORD, kwcl_IconManagerHighlight },
  475.     { "iconmanagers",        ICONMGRS, 0 },
  476.     { "iconmanagershow",    ICONMGR_SHOW, 0 },
  477.     { "iconmgr",        ICONMGR, 0 },
  478.     { "iconregion",        ICON_REGION, 0 },
  479.     { "icons",            ICONS, 0 },
  480.     { "interpolatemenucolors",    KEYWORD, kw0_InterpolateMenuColors },
  481.     { "l",            LOCK, 0 },
  482.     { "left",            JKEYWORD, J_LEFT },
  483.     { "lefttitlebutton",    LEFT_TITLEBUTTON, 0 },
  484.     { "lock",            LOCK, 0 },
  485.     { "m",            META, 0 },
  486.     { "maketitle",        MAKE_TITLE, 0 },
  487.     { "maxwindowsize",        SKEYWORD, kws_MaxWindowSize },
  488.     { "menu",            MENU, 0 },
  489.     { "menubackground",        CKEYWORD, kwc_MenuBackground },
  490.     { "menufont",        SKEYWORD, kws_MenuFont },
  491.     { "menuforeground",        CKEYWORD, kwc_MenuForeground },
  492.     { "menushadowcolor",    CKEYWORD, kwc_MenuShadowColor },
  493.     { "menutitlebackground",    CKEYWORD, kwc_MenuTitleBackground },
  494.     { "menutitleforeground",    CKEYWORD, kwc_MenuTitleForeground },
  495.     { "meta",            META, 0 },
  496.     { "mod",            META, 0 },  /* fake it */
  497.     { "monochrome",        MONOCHROME, 0 },
  498.     { "move",            MOVE, 0 },
  499.     { "movedelta",        NKEYWORD, kwn_MoveDelta },
  500.     { "nobackingstore",        KEYWORD, kw0_NoBackingStore },
  501.     { "nocasesensitive",    KEYWORD, kw0_NoCaseSensitive },
  502.     { "nodefaults",        KEYWORD, kw0_NoDefaults },
  503.     { "nograbserver",        KEYWORD, kw0_NoGrabServer },
  504.     { "nohighlight",        NO_HILITE, 0 },
  505.     { "noiconmanagers",        KEYWORD, kw0_NoIconManagers },
  506.     { "nomenushadows",        KEYWORD, kw0_NoMenuShadows },
  507.     { "noraiseondeiconify",    KEYWORD, kw0_NoRaiseOnDeiconify },
  508.     { "noraiseonmove",        KEYWORD, kw0_NoRaiseOnMove },
  509.     { "noraiseonresize",    KEYWORD, kw0_NoRaiseOnResize },
  510.     { "noraiseonwarp",        KEYWORD, kw0_NoRaiseOnWarp },
  511.     { "north",            DKEYWORD, D_NORTH },
  512.     { "nosaveunders",        KEYWORD, kw0_NoSaveUnders },
  513.     { "nostackmode",        NO_STACKMODE, 0 },
  514.     { "notitle",        NO_TITLE, 0 },
  515.     { "notitlefocus",        KEYWORD, kw0_NoTitleFocus },
  516.     { "notitlehighlight",    NO_TITLE_HILITE, 0 },
  517.     { "noversion",        KEYWORD, kw0_NoVersion },
  518.     { "opaquemove",        KEYWORD, kw0_OpaqueMove },
  519.     { "pixmaps",        PIXMAPS, 0 },
  520.     { "r",            ROOT, 0 },
  521.     { "randomplacement",    KEYWORD, kw0_RandomPlacement },
  522.     { "resize",            RESIZE, 0 },
  523.     { "resizefont",        SKEYWORD, kws_ResizeFont },
  524.     { "restartpreviousstate",    KEYWORD, kw0_RestartPreviousState },
  525.     { "right",            JKEYWORD, J_RIGHT },
  526.     { "righttitlebutton",    RIGHT_TITLEBUTTON, 0 },
  527.     { "root",            ROOT, 0 },
  528.     { "s",            SHIFT, 0 },
  529.     { "savecolor",              SAVECOLOR, 0},
  530.     { "select",            SELECT, 0 },
  531.     { "shift",            SHIFT, 0 },
  532.     { "showiconmanager",    KEYWORD, kw0_ShowIconManager },
  533.     { "sorticonmanager",    KEYWORD, kw0_SortIconManager },
  534.     { "south",            DKEYWORD, D_SOUTH },
  535.     { "squeezetitle",        SQUEEZE_TITLE, 0 },
  536.     { "starticonified",        START_ICONIFIED, 0 },
  537.     { "t",            TITLE, 0 },
  538.     { "title",            TITLE, 0 },
  539.     { "titlebackground",    CLKEYWORD, kwcl_TitleBackground },
  540.     { "titlebuttonborderwidth",    NKEYWORD, kwn_TitleButtonBorderWidth },
  541.     { "titlefont",        SKEYWORD, kws_TitleFont },
  542.     { "titleforeground",    CLKEYWORD, kwcl_TitleForeground },
  543.     { "titlehighlight",        TITLE_HILITE, 0 },
  544.     { "titlepadding",        NKEYWORD, kwn_TitlePadding },
  545.     { "unknownicon",        SKEYWORD, kws_UnknownIcon },
  546.     { "usepposition",        SKEYWORD, kws_UsePPosition },
  547.     { "w",            WINDOW, 0 },
  548.     { "wait",            WAIT, 0 },
  549.     { "warpcursor",        WARP_CURSOR, 0 },
  550.     { "warpunmapped",        KEYWORD, kw0_WarpUnmapped },
  551.     { "west",            DKEYWORD, D_WEST },
  552.     { "window",            WINDOW, 0 },
  553.     { "windowfunction",        WINDOW_FUNCTION, 0 },
  554.     { "windowring",        WINDOW_RING, 0 },
  555.     { "xorvalue",        NKEYWORD, kwn_XorValue },
  556.     { "zoom",            ZOOM, 0 },
  557. };
  558.  
  559. static int numkeywords = (sizeof(keytable)/sizeof(keytable[0]));
  560.  
  561. int parse_keyword (s, nump)
  562.     char *s;
  563.     int *nump;
  564. {
  565.     register int lower = 0, upper = numkeywords - 1;
  566.  
  567.     XmuCopyISOLatin1Lowered (s, s);
  568.     while (lower <= upper) {
  569.         int middle = (lower + upper) / 2;
  570.     TwmKeyword *p = &keytable[middle];
  571.         int res = strcmp (p->name, s);
  572.  
  573.         if (res < 0) {
  574.             lower = middle + 1;
  575.         } else if (res == 0) {
  576.         *nump = p->subnum;
  577.             return p->value;
  578.         } else {
  579.             upper = middle - 1;
  580.         }
  581.     }
  582.     return ERRORTOKEN;
  583. }
  584.  
  585.  
  586.  
  587. /*
  588.  * action routines called by grammar
  589.  */
  590.  
  591. int do_single_keyword (keyword)
  592.     int keyword;
  593. {
  594.     switch (keyword) {
  595.       case kw0_NoDefaults:
  596.     Scr->NoDefaults = TRUE;
  597.     return 1;
  598.  
  599.       case kw0_AutoRelativeResize:
  600.     Scr->AutoRelativeResize = TRUE;
  601.     return 1;
  602.  
  603.       case kw0_ForceIcons:
  604.     if (Scr->FirstTime) Scr->ForceIcon = TRUE;
  605.     return 1;
  606.  
  607.       case kw0_NoIconManagers:
  608.     Scr->NoIconManagers = TRUE;
  609.     return 1;
  610.  
  611.       case kw0_OpaqueMove:
  612.     Scr->OpaqueMove = TRUE;
  613.     return 1;
  614.  
  615.       case kw0_InterpolateMenuColors:
  616.     if (Scr->FirstTime) Scr->InterpolateMenuColors = TRUE;
  617.     return 1;
  618.  
  619.       case kw0_NoVersion:
  620.     /* obsolete */
  621.     return 1;
  622.  
  623.       case kw0_SortIconManager:
  624.     if (Scr->FirstTime) Scr->SortIconMgr = TRUE;
  625.     return 1;
  626.  
  627.       case kw0_NoGrabServer:
  628.     Scr->NoGrabServer = TRUE;
  629.     return 1;
  630.  
  631.       case kw0_NoMenuShadows:
  632.     if (Scr->FirstTime) Scr->Shadow = FALSE;
  633.     return 1;
  634.  
  635.       case kw0_NoRaiseOnMove:
  636.     if (Scr->FirstTime) Scr->NoRaiseMove = TRUE;
  637.     return 1;
  638.  
  639.       case kw0_NoRaiseOnResize:
  640.     if (Scr->FirstTime) Scr->NoRaiseResize = TRUE;
  641.     return 1;
  642.  
  643.       case kw0_NoRaiseOnDeiconify:
  644.     if (Scr->FirstTime) Scr->NoRaiseDeicon = TRUE;
  645.     return 1;
  646.  
  647.       case kw0_DontMoveOff:
  648.     Scr->DontMoveOff = TRUE;
  649.     return 1;
  650.  
  651.       case kw0_NoBackingStore:
  652.     Scr->BackingStore = FALSE;
  653.     return 1;
  654.  
  655.       case kw0_NoSaveUnders:
  656.     Scr->SaveUnder = FALSE;
  657.     return 1;
  658.  
  659.       case kw0_RestartPreviousState:
  660.     RestartPreviousState = True;
  661.     return 1;
  662.  
  663.       case kw0_ClientBorderWidth:
  664.     if (Scr->FirstTime) Scr->ClientBorderWidth = TRUE;
  665.     return 1;
  666.  
  667.       case kw0_NoTitleFocus:
  668.     Scr->TitleFocus = FALSE;
  669.     return 1;
  670.  
  671.       case kw0_RandomPlacement:
  672.     Scr->RandomPlacement = TRUE;
  673.     return 1;
  674.  
  675.       case kw0_DecorateTransients:
  676.     Scr->DecorateTransients = TRUE;
  677.     return 1;
  678.  
  679.       case kw0_ShowIconManager:
  680.     Scr->ShowIconManager = TRUE;
  681.     return 1;
  682.  
  683.       case kw0_NoCaseSensitive:
  684.     Scr->CaseSensitive = FALSE;
  685.     return 1;
  686.  
  687.       case kw0_NoRaiseOnWarp:
  688.     Scr->NoRaiseWarp = TRUE;
  689.     return 1;
  690.  
  691.       case kw0_WarpUnmapped:
  692.     Scr->WarpUnmapped = TRUE;
  693.     return 1;
  694.     }
  695.  
  696.     return 0;
  697. }
  698.  
  699.  
  700. int do_string_keyword (keyword, s)
  701.     int keyword;
  702.     char *s;
  703. {
  704.     switch (keyword) {
  705.       case kws_UsePPosition:
  706.     { 
  707.         int ppos = ParseUsePPosition (s);
  708.         if (ppos < 0) {
  709.         twmrc_error_prefix();
  710.         fprintf (stderr,
  711.              "ignoring invalid UsePPosition argument \"%s\"\n", s);
  712.         } else {
  713.         Scr->UsePPosition = ppos;
  714.         }
  715.         return 1;
  716.     }
  717.  
  718.       case kws_IconFont:
  719.     if (!Scr->HaveFonts) Scr->IconFont.name = s;
  720.     return 1;
  721.  
  722.       case kws_ResizeFont:
  723.     if (!Scr->HaveFonts) Scr->SizeFont.name = s;
  724.     return 1;
  725.  
  726.       case kws_MenuFont:
  727.     if (!Scr->HaveFonts) Scr->MenuFont.name = s;
  728.     return 1;
  729.  
  730.       case kws_TitleFont:
  731.     if (!Scr->HaveFonts) Scr->TitleBarFont.name = s;
  732.     return 1;
  733.  
  734.       case kws_IconManagerFont:
  735.     if (!Scr->HaveFonts) Scr->IconManagerFont.name = s;
  736.     return 1;
  737.  
  738.       case kws_UnknownIcon:
  739.     if (Scr->FirstTime) GetUnknownIcon (s);
  740.     return 1;
  741.  
  742.       case kws_IconDirectory:
  743.     if (Scr->FirstTime) Scr->IconDirectory = ExpandFilename (s);
  744.     return 1;
  745.  
  746.       case kws_MaxWindowSize:
  747.     JunkMask = XParseGeometry (s, &JunkX, &JunkY, &JunkWidth, &JunkHeight);
  748.     if ((JunkMask & (WidthValue | HeightValue)) != 
  749.         (WidthValue | HeightValue)) {
  750.         twmrc_error_prefix();
  751.         fprintf (stderr, "bad MaxWindowSize \"%s\"\n", s);
  752.         return 0;
  753.     }
  754.     if (JunkWidth <= 0 || JunkHeight <= 0) {
  755.         twmrc_error_prefix();
  756.         fprintf (stderr, "MaxWindowSize \"%s\" must be positive\n", s);
  757.         return 0;
  758.     }
  759.     Scr->MaxWindowWidth = JunkWidth;
  760.     Scr->MaxWindowHeight = JunkHeight;
  761.     return 1;
  762.     }
  763.  
  764.     return 0;
  765. }
  766.  
  767.  
  768. int do_number_keyword (keyword, num)
  769.     int keyword;
  770.     int num;
  771. {
  772.     switch (keyword) {
  773.       case kwn_ConstrainedMoveTime:
  774.     ConstrainedMoveTime = num;
  775.     return 1;
  776.  
  777.       case kwn_MoveDelta:
  778.     Scr->MoveDelta = num;
  779.     return 1;
  780.  
  781.       case kwn_XorValue:
  782.     if (Scr->FirstTime) Scr->XORvalue = num;
  783.     return 1;
  784.  
  785.       case kwn_FramePadding:
  786.     if (Scr->FirstTime) Scr->FramePadding = num;
  787.     return 1;
  788.  
  789.       case kwn_TitlePadding:
  790.     if (Scr->FirstTime) Scr->TitlePadding = num;
  791.     return 1;
  792.  
  793.       case kwn_ButtonIndent:
  794.     if (Scr->FirstTime) Scr->ButtonIndent = num;
  795.     return 1;
  796.  
  797.       case kwn_BorderWidth:
  798.     if (Scr->FirstTime) Scr->BorderWidth = num;
  799.     return 1;
  800.  
  801.       case kwn_IconBorderWidth:
  802.     if (Scr->FirstTime) Scr->IconBorderWidth = num;
  803.     return 1;
  804.  
  805.       case kwn_TitleButtonBorderWidth:
  806.     if (Scr->FirstTime) Scr->TBInfo.border = num;
  807.     return 1;
  808.  
  809.     }
  810.  
  811.     return 0;
  812. }
  813.  
  814. name_list **do_colorlist_keyword (keyword, colormode, s)
  815.     int keyword;
  816.     int colormode;
  817.     char *s;
  818. {
  819.     switch (keyword) {
  820.       case kwcl_BorderColor:
  821.     GetColor (colormode, &Scr->BorderColor, s);
  822.     return &Scr->BorderColorL;
  823.  
  824.       case kwcl_IconManagerHighlight:
  825.     GetColor (colormode, &Scr->IconManagerHighlight, s);
  826.     return &Scr->IconManagerHighlightL;
  827.  
  828.       case kwcl_BorderTileForeground:
  829.     GetColor (colormode, &Scr->BorderTileC.fore, s);
  830.     return &Scr->BorderTileForegroundL;
  831.  
  832.       case kwcl_BorderTileBackground:
  833.     GetColor (colormode, &Scr->BorderTileC.back, s);
  834.     return &Scr->BorderTileBackgroundL;
  835.  
  836.       case kwcl_TitleForeground:
  837.     GetColor (colormode, &Scr->TitleC.fore, s);
  838.     return &Scr->TitleForegroundL;
  839.  
  840.       case kwcl_TitleBackground:
  841.     GetColor (colormode, &Scr->TitleC.back, s);
  842.     return &Scr->TitleBackgroundL;
  843.  
  844.       case kwcl_IconForeground:
  845.     GetColor (colormode, &Scr->IconC.fore, s);
  846.     return &Scr->IconForegroundL;
  847.  
  848.       case kwcl_IconBackground:
  849.     GetColor (colormode, &Scr->IconC.back, s);
  850.     return &Scr->IconBackgroundL;
  851.  
  852.       case kwcl_IconBorderColor:
  853.     GetColor (colormode, &Scr->IconBorderColor, s);
  854.     return &Scr->IconBorderColorL;
  855.  
  856.       case kwcl_IconManagerForeground:
  857.     GetColor (colormode, &Scr->IconManagerC.fore, s);
  858.     return &Scr->IconManagerFL;
  859.  
  860.       case kwcl_IconManagerBackground:
  861.     GetColor (colormode, &Scr->IconManagerC.back, s);
  862.     return &Scr->IconManagerBL;
  863.     }
  864.     return NULL;
  865. }
  866.  
  867. int do_color_keyword (keyword, colormode, s)
  868.     int keyword;
  869.     int colormode;
  870.     char *s;
  871. {
  872.     switch (keyword) {
  873.       case kwc_DefaultForeground:
  874.     GetColor (colormode, &Scr->DefaultC.fore, s);
  875.     return 1;
  876.  
  877.       case kwc_DefaultBackground:
  878.     GetColor (colormode, &Scr->DefaultC.back, s);
  879.     return 1;
  880.  
  881.       case kwc_MenuForeground:
  882.     GetColor (colormode, &Scr->MenuC.fore, s);
  883.     return 1;
  884.  
  885.       case kwc_MenuBackground:
  886.     GetColor (colormode, &Scr->MenuC.back, s);
  887.     return 1;
  888.  
  889.       case kwc_MenuTitleForeground:
  890.     GetColor (colormode, &Scr->MenuTitleC.fore, s);
  891.     return 1;
  892.  
  893.       case kwc_MenuTitleBackground:
  894.     GetColor (colormode, &Scr->MenuTitleC.back, s);
  895.     return 1;
  896.  
  897.       case kwc_MenuShadowColor:
  898.     GetColor (colormode, &Scr->MenuShadowColor, s);
  899.     return 1;
  900.  
  901.     }
  902.  
  903.     return 0;
  904. }
  905.  
  906. /*
  907.  * put_pixel_on_root() Save a pixel value in twm root window color property.
  908.  */
  909. put_pixel_on_root(pixel)                                 
  910.     Pixel pixel;                                         
  911. {                                                        
  912.   int           i, addPixel = 1;
  913.   Atom          pixelAtom, retAtom;                     
  914.   int           retFormat;
  915.   unsigned long nPixels, retAfter;                     
  916.   Pixel        *retProp;
  917.   pixelAtom = XInternAtom(dpy, "_MIT_PRIORITY_COLORS", True);        
  918.   XGetWindowProperty(dpy, Scr->Root, pixelAtom, 0, 8192, 
  919.              False, XA_CARDINAL, &retAtom,       
  920.              &retFormat, &nPixels, &retAfter,    
  921.              (unsigned char **)&retProp);
  922.  
  923.   for (i=0; i< nPixels; i++)                             
  924.       if (pixel == retProp[i]) addPixel = 0;             
  925.                                                          
  926.   if (addPixel)                                          
  927.       XChangeProperty (dpy, Scr->Root, _XA_MIT_PRIORITY_COLORS,
  928.                XA_CARDINAL, 32, PropModeAppend,  
  929.                (unsigned char *)&pixel, 1);                       
  930. }                                                        
  931.  
  932. /*
  933.  * do_string_savecolor() save a color from a string in the twmrc file.
  934.  */
  935. int do_string_savecolor(colormode, s)
  936.      int colormode;
  937.      char *s;
  938. {
  939.   Pixel p;
  940.   GetColor(colormode, &p, s);
  941.   put_pixel_on_root(p);
  942. }
  943.  
  944. /*
  945.  * do_var_savecolor() save a color from a var in the twmrc file.
  946.  */
  947. typedef struct _cnode {int i; struct _cnode *next;} Cnode, *Cptr;
  948. Cptr chead = NULL;
  949.  
  950. int do_var_savecolor(key)
  951. int key;
  952. {
  953.   Cptr cptrav, cpnew;
  954.   if (!chead) {
  955.     chead = (Cptr)malloc(sizeof(Cnode));
  956.     chead->i = key; chead->next = NULL;
  957.   }
  958.   else {
  959.     cptrav = chead;
  960.     while (cptrav->next != NULL) { cptrav = cptrav->next; }
  961.     cpnew = (Cptr)malloc(sizeof(Cnode));
  962.     cpnew->i = key; cpnew->next = NULL; cptrav->next = cpnew;
  963.   }
  964. }
  965.  
  966. /*
  967.  * assign_var_savecolor() traverse the var save color list placeing the pixels
  968.  *                        in the root window property.
  969.  */
  970. void assign_var_savecolor()
  971. {
  972.   Cptr cp = chead;
  973.   while (cp != NULL) {
  974.     switch (cp->i) {
  975.     case kwcl_BorderColor:
  976.       put_pixel_on_root(Scr->BorderColor);
  977.       break;
  978.     case kwcl_IconManagerHighlight:
  979.       put_pixel_on_root(Scr->IconManagerHighlight);
  980.       break;
  981.     case kwcl_BorderTileForeground:
  982.       put_pixel_on_root(Scr->BorderTileC.fore);
  983.       break;
  984.     case kwcl_BorderTileBackground:
  985.       put_pixel_on_root(Scr->BorderTileC.back);
  986.       break;
  987.     case kwcl_TitleForeground:
  988.       put_pixel_on_root(Scr->TitleC.fore);
  989.       break;
  990.     case kwcl_TitleBackground:
  991.       put_pixel_on_root(Scr->TitleC.back);
  992.       break;
  993.     case kwcl_IconForeground:
  994.       put_pixel_on_root(Scr->IconC.fore);
  995.       break;
  996.     case kwcl_IconBackground:
  997.       put_pixel_on_root(Scr->IconC.back);
  998.       break;
  999.     case kwcl_IconBorderColor:
  1000.       put_pixel_on_root(Scr->IconBorderColor);
  1001.       break;
  1002.     case kwcl_IconManagerForeground:
  1003.       put_pixel_on_root(Scr->IconManagerC.fore);
  1004.       break;
  1005.     case kwcl_IconManagerBackground:
  1006.       put_pixel_on_root(Scr->IconManagerC.back);
  1007.       break;
  1008.     }
  1009.     cp = cp->next;
  1010.   }
  1011.   if (chead) {
  1012.     free(chead);
  1013.     chead = NULL;
  1014.   }
  1015. }
  1016.  
  1017. static int ParseUsePPosition (s)
  1018.     register char *s;
  1019. {
  1020.     XmuCopyISOLatin1Lowered (s, s);
  1021.  
  1022.     if (strcmp (s, "off") == 0) {
  1023.     return PPOS_OFF;
  1024.     } else if (strcmp (s, "on") == 0) {
  1025.     return PPOS_ON;
  1026.     } else if (strcmp (s, "non-zero") == 0 ||
  1027.            strcmp (s, "nonzero") == 0) {
  1028.     return PPOS_NON_ZERO;
  1029.     }
  1030.  
  1031.     return -1;
  1032. }
  1033.  
  1034.  
  1035. do_squeeze_entry (list, name, justify, num, denom)
  1036.     name_list **list;            /* squeeze or dont-squeeze list */
  1037.     char *name;                /* window name */
  1038.     int justify;            /* left, center, right */
  1039.     int num;                /* signed num */
  1040.     int denom;                /* 0 or indicates fraction denom */
  1041. {
  1042.     int absnum = (num < 0 ? -num : num);
  1043.  
  1044.     if (denom < 0) {
  1045.     twmrc_error_prefix();
  1046.     fprintf (stderr, "negative SqueezeTitle denominator %d\n", denom);
  1047.     return;
  1048.     }
  1049.     if (absnum > denom && denom != 0) {
  1050.     twmrc_error_prefix();
  1051.     fprintf (stderr, "SqueezeTitle fraction %d/%d outside window\n",
  1052.          num, denom);
  1053.     return;
  1054.     }
  1055.     if (denom == 1) {
  1056.     twmrc_error_prefix();
  1057.     fprintf (stderr, "useless SqueezeTitle faction %d/%d, assuming 0/0\n",
  1058.          num, denom);
  1059.     num = 0;
  1060.     denom = 0;
  1061.     }
  1062.  
  1063.     if (HasShape) {
  1064.     SqueezeInfo *sinfo;
  1065.     sinfo = (SqueezeInfo *) malloc (sizeof(SqueezeInfo));
  1066.  
  1067.     if (!sinfo) {
  1068.         twmrc_error_prefix();
  1069.         fprintf (stderr, "unable to allocate %d bytes for squeeze info\n",
  1070.              sizeof(SqueezeInfo));
  1071.         return;
  1072.     }
  1073.     sinfo->justify = justify;
  1074.     sinfo->num = num;
  1075.     sinfo->denom = denom;
  1076.     AddToList (list, name, (char *) sinfo);
  1077.     }
  1078. }
  1079.